/* ----------------------------------------------------------------------------------------------------------------
 * AnimationRenderer
 * ----------------------------------------------------------------------------------------------------------------
 */
package pure.engine.renderer 
{
	import flash.display.BitmapData;
	import flash.events.Event;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import pure.debug.Logger;
	import pure.engine.system.ProcessManager;
	
	import pure.engine.renderer.sections.Action;
	import pure.engine.renderer.sections.Section;
	import pure.engine.renderer.sections.SectionManager;
	import pure.engine.system.ns_despair;
		
	use namespace ns_despair;
	
	/**
	 * 动画渲染器
	 * 
	 * @author Pure
	 * 
	 * [Hint] - 当动画渲染器不可见时，任何操作无效化
	 *        - 在visible为true时，对动画渲染器进行操作
	 */
public class AnimationRenderer extends Renderer implements IAnimation
{


	
	
	
	
	//======================
	// Property
	//======================

	

	// 加入或改变片段
	
	// [Feature] - 片段属性不可为空，
	public function get section():String
	{
		return m_sectionName;
	}
	
	public function set section(sectionName:String):void
	{
		if (m_sectionName == sectionName)  return;
		
		if (m_flag == -1)
		{
			ProcessManager.instance.addTickObject(this, TICK_PRIORITY);
		}
		
		m_section  =  SectionManager.getSection(m_sectionName = sectionName);
		m_x        =  m_section.m_x;
		m_y        =  m_section.m_y;
		m_range    =  m_section.m_range;
		m_flag     =  0;
		m_opcode   =  m_pointer  =  1;
		
		if (m_visible && m_dirtyFlag > -1)  m_dirtyFlag = 2;
	}
	

	// 播放速度
	public function get playSpeed():Number { return m_playSpeed; }
	public function set playSpeed(v:Number):void
	{
		if(m_playSpeed != v)
		{
			m_playSpeed = v;
			//if(_actionOrPointer is String)
			//{
				//cachedDelayB = _section.getActionByName(_actionOrPointer).delay / m_playSpeed;
			//}
		}
	}
	
	
	// 是否正在播放
	public function get playing():Boolean
	{
		return m_flag > 0;
	}

	
	// 返回当前播放位置，[-2]空片段，[-1]未播放，[0 ~ 1]进度
	public function get position():Number
	{
		if (m_flag > 0)   return ((cachedIndex + cachedTime / cachedDelayB) / cachedLength);
		if (m_flag == 0)  return -1;
		return -2;
	}
	
	
	// 是否可见
	override public function set visible(b:Boolean):void
	{ 
		super.visible = b;
		if (b)
		{
			resume();
			if (m_flag != -1)
			{
				ProcessManager.instance.addTickObject(this, TICK_PRIORITY);
			}
		}
		else
		{
			stop();
			if (m_flag != -1)
			{
				ProcessManager.instance.removeTickObject(this);
			}
		}
	}
	
	
	
	
	

	//======================
	// Base
	//======================
		
	
	// 普通播放
	
	// [params] - 动作名字
	// [params] - 完成回调
	// [params] - 强制重播
	// [return] - 持续时间(秒)，可使用该参数延迟调用其他方法
	public function play(actionName:String, onComplete:Function = null, ...args):Number
	{
		if (m_opcode != actionName || m_onComplete != onComplete || m_params != args)
		{
			if(_playAction(actionName, 0, 0))
			{
				m_onComplete = onComplete;
				m_params     = args
				m_flag = 1;
				return cachedDelayB * (cachedLength - 1) * 0.001;
			}
			return 0;
		}

		return cachedDelayB * cachedIndex * 0.001; 
	}

	
	// 重复播放
	
	// [params] - 动作名字
	public function repeat(actionName:String):void
	{
		if (m_opcode != actionName)
		{
			if(_playAction(actionName, 0, 0))
			{
				m_flag = 2;
			}
		}
	}


	// 计时播放
	
	// [Hint] - 播放速度由某因素决定，如攻击速度
	// [params] - 动作名字
	// [params] - 持续时间(秒)
	public function tick(actionName:String, duration:Number, onComplete:Function = null, ...args):void
	{
		if(_playAction(actionName, 0, duration * 1000))
		{
			m_onComplete = onComplete;
			m_params     = args
			m_flag = 1;
		}
	}
	
	
	// 改变指针
	public function setPointer(pointer:int):void
	{
		if (m_visible && (m_opcode = pointer) != m_pointer)
		{
			m_pointer = pointer;
			
			if (m_dirtyFlag == 0)  m_dirtyFlag = 1;
			if (m_flag > 0)        m_flag = 0;
		}
	}
	
	
	// 停止
	public function stop():void
	{
		if (m_flag <= 0)  return;
		
		m_oldFlag  =  m_flag;
		m_flag     =  0;
	}
	
	
	// 再开
	public function resume():void
	{
		if (m_flag > 0 && m_oldFlag == 0)  return;
		
		m_flag  =  m_oldFlag;
	}
	
	
	// 重置
	
	// [Hint] - 回到当前动作起点
	public function reset(autoPlay:Boolean):void
	{
		if (m_flag > 0)
		{
			cachedIndex = cachedTime = 0;
			if (!autoPlay)         m_flag = 0;
			if (m_dirtyFlag == 0)  m_dirtyFlag = 1;
		}
	}
	
	
	// 停止-再开
	public function togglePause():void
	{
		if (m_flag > 0)
		{
			stop();
		}
		else
		{
			resume()
		}
	}
	


	
	
	/* ----------------------------------------------------------------------------------------------------------------
	 * ★★★★★★★★★★★★★★★★★★★★★  private  ★★★★★★★★★★★★★★★★★★★★★
	 * ----------------------------------------------------------------------------------------------------------------
	 */


	 
	// 更新
	public function onTick(elapsedT:Number):void 
	{
		var pointer:int;
		
		if (m_flag > 0)
		{
			if ((cachedTime += elapsedT) >= cachedDelayB)
			{
				if (++cachedIndex >= cachedLength - 1) 
				{	
					// 循环
					if (m_flag == 2)
					{
						cachedIndex = 0;
					}
					// 普通播放
					else
					{
						m_flag = cachedTime = 0;
						if (m_onComplete != null)  m_onComplete();
						return;
					}
				}
				// 更新指针
				if ((pointer = m_group[cachedIndex]) != m_pointer)
				{
					m_pointer = pointer;
					if (m_dirtyFlag == 0)  m_dirtyFlag = 1;
				}
				
				cachedTime -=  cachedDelayB;	
			}
		}
		// 空片段时，不会渲染
		else if(m_flag == -1)
		{
			m_dirtyFlag = 0
		}
	}
	
	
	// 播放动作
	// [Feature] - 帧1-2-3-4...由最初帧到最后帧，改变次数为 numFrame - 1
	// [Process] - [-1]空片段，[0]停止，[1]播放，[2]重复
	
	// [param] - <actionName>  指令，int/String类型
	// [param] - <index>       当前索引
	// [param] - <duration>    手动持续时间(毫秒)，为-1时，使用动作默认持续时间
	// [return] - 是否播放状态
	protected function _playAction(actionName:*, index:int, duration:int):Boolean 
	{
		var action:Action;
		
		if (m_flag == -1)
		{
			Logger.reportError(this, '_playAction', '未加入片段.');
		}
		
		// 改变动作
		action = m_section.getActionByName(m_opcode = actionName)
		if (!action) 
		{
			Logger.reportError(this, '_playAction', '片段<' + m_section.m_name +'>，未知动作<' + actionName +'>.');
		}
		
		m_group       =  action.group;
		cachedLength  =  m_group.length;
		cachedIndex   =  index;
		m_pointer     =  m_group[index];

		if (m_dirtyFlag == 0)  m_dirtyFlag = 1;
		
		// 单指针
		if (cachedLength == 1) 
		{
			if (m_flag > 0)  m_flag = 0;
			
			return false;
		}

		if (duration > 0)
		{
			cachedDelayA = cachedDelayB = (duration / (cachedLength - 1)) >> 0;
		}
		else
		{
			cachedDelayA = action.delay;
			cachedDelayB = (cachedDelayA / m_playSpeed) >> 0;
		}
		cachedTime = 0;
		
		return true;
	}

	
	// Template !!
	override protected function _generatePrimaryImage():void 
	{
		m_imageA = m_section.getBitmapByPointer(m_pointer);
	}
	

	override ns_despair function destroy():void
	{
		m_section     =  null;
		m_group       =  null;
		m_onComplete  =  null;
		m_params      =  null;
		ProcessManager.instance.removeTickObject(this);
		
		super.destroy();
	}
	
	
	
	
	
	
	
	
	//======================
	// Member
	//======================

	
	protected var m_section:Section;  // 片段加入后，渲染器destroy前，无法null.

	protected var m_sectionName:String;  // 片段名字
	
	protected var m_opcode:*;  // 当前指令，保存了上一次操作
	
	protected var m_group:Vector.<int>;  // 当前组
		
	protected var m_pointer:int;  // 当前指针，默认第一个
	
	protected var m_flag:int = -1, m_oldFlag:int;  // 动画状态
	
	protected var m_playSpeed:Number = 1.0;

	protected var m_onComplete:Function;
	
	protected var m_params:Array;
	
	

	//======================
	// Cached Object
	//======================
	
	
	protected var cachedIndex:int, cachedLength:int, cachedTime:int, cachedDelayA:int, cachedDelayB:int;
	
	protected static const TICK_PRIORITY:int = -5;
	
}
}